<html>
<head>
<title>Brython</title>
<link rel="stylesheet" href="../doc_brython.css">
<meta charset="iso-8859-1">
</head>
<body>
<a name="modele"><h3>Compiling and running</h3>
</ol>
The <b>brython.js</b> file is created by the grouping of several scripts :
<ul>
<li><b>py_tokenizer.js</b> : breaks down the Python source code into tokens (identifiers, literals, operators, delimiters, etc.)
<li><b>py2js.js</b> : does the conversion between the tokens and the Javascript code
<li><b>py_tokens.js</b> : classes to manipulate the tokens
<li><b>py_utils.js</b> : utility functions (type conversion between Python and Javascript)
<li><b>py_string.js</b> : implementation of the Python str class from the Javascript String object
<li><b>py_list.js</b> : implementation of the Python list class from the Javascript Array object
<li><b>py_classes.js</b> : all other types and built-in functions of Python
<li><b>py_import.js</b> : implementation of import
<li><b>py_dom.js</b> : interaction with the HTML document (DOM)
<li><b>py_ajax.js</b> : Ajax implementation
<li><b>py_local_storage.js</b> : implementation of the HTML5 local storage
<li><b>py_svg.py</b> : SVG support (vector graphics)
</ul>

When "compiling" and running a script, Brython goes through the following phases :
<ol>
<li>if the debug level is greater than 0, a line containing the number of the next line to be run is added after each line of Python source code, but not if this would cause a syntax error (eg, before an <tt>except</tt> or an <tt>else</tt>)
<p>
<li>break down of Python source code into tokens
<br>This is done by the <tt>py_tokenizer.js</tt> script. Tokens are Javascript lists with 3 elements [<em>type, value, position</em>]. <em>position</em> is the ranking of the first character of the token in the Python source code. The other 2 elements can have the following values :
<ul>
<li><tt>["indent",<em>indentation</em>]</tt> : always present at the beginning of each line, <em>indentation</em> is a number
<li><tt>["newline","\n"]</tt> : linefeed
<li><tt>["str",<em>string</em>]</tt> : string type literal
<li><tt>["int",<em>number</em>]</tt> : integer type literal
<li><tt>["float",<em>number</em>]</tt> : floating point type literal
<li><tt>["id",<em>string</em>]</tt> : variable identifier (string)
<li><tt>["qualifier",<em>string</em>]</tt> : a name following a dot, such as <tt>bar</tt> in <tt>foo.bar</tt> (foo dot bar)
<li><tt>["keyword",<em>value</em>]</tt> : Python keyword (string)
<li><tt>["bracket",<em>value</em>]</tt> : opening or closing parenthesis, bracket or brace. The value can be one of <em>()[]{}</em>
<li><tt>["point","."]</tt> : a period
<li><tt>["delimiter",<em>string</em>]</tt> : a delimiter, with a value of <em>:</em>, <em>,</em> or <em>=</em> inside parentheses (<tt>foo(x=0)</tt> syntax)
<li><tt>["assign","="]</tt> : = sign when it is not inside a parenthesis
<li><tt>["operator",<em>string</em>]</tt> : an operator
</ul>
<p>In this step, errors may be reported : 
<ul>
<li>indentation error
<li>unterminated string
<li>unbalanced parentheses
<li>illegal character
<li>keyword that is unsupported by the Python implementation of Brython
<li>unusable identifier because it conflicts with one of the JavaScript reserved words  (eg <em>window, document, status...</em>)
</ul>
<p>
<li>Translation of tokens into Javascript code
<p>This is done by the <tt>py2js.js</tt>, <tt>py_tokens.js</tt> and <tt>py_utils.js</tt> scripts, in the following order :
<ol>
<li>replacing the sequence <tt>not in</tt> by the <tt>__not_in__</tt> operator
<li>conversion of parentheses, brackets and braces in tuples, lists et dictionaries
<li>conversion of arguments in the function definition (<tt>def foo(x,y=1,*args,**kw)</tt>)
<li>conversion of arguments as keywords in function calls (<tt>foo(b=1)</tt>)
<li>resolving multiple + and - (++ becomes +, -+- becomes -, etc.) and unary operators - and +
<li>replacing <tt>import foo</tt> by <tt>Import(foo)</tt>
<li>translation of <tt>try / except / finally / else</tt> blocks
<li>translation of <tt>assert</tt>
<li>translation of indentation into braces for blocks beginning with <tt>if, else, elif, def, for, try, finally</tt>
<li>replacing <tt>not x</tt> with <tt>$not(x)</tt>
<li>expansion of short form adding assignments (<tt>x += 1</tt>) with a full explicit operation and assignment (<tt>x = x+1</tt>)
<li>replacement of operators by the equivalent functions : <tt>x+y</tt> becomes <tt>x.__add__(y)</tt>
<li>processing of conditions combined with <tt>and</tt> and <tt>or</tt>
<li>chained assignments (<tt>x=y=0</tt>), direct (<tt>x=y</tt>) and multiples (<tt>x,y=a,b</tt>)
<li>access (<tt>a=foo[x]</tt>) or assignment (<tt>foo[x] = 0</tt>) to keys and slices
<li>access (<tt>a=foo.x</tt>) or assignment (<tt>foo.x = 0</tt>) to attributes
</ol>
<p>
<li>Execution of the generated Javascript code
<p>At runtime, the generated script can make use of :
<ul>
<li>classes defined in <tt>py_classes.js, py_string.js, py_list.js, py_dom.js, py_ajax.js, py_local_storage.js, py_svg.js</tt>
<li>builtin functions, not accessible in Python (their name start with $) and which can be mostly found in <tt>$py_utils.js</tt>. The most important are :
<ul>
<li><tt>$JS2py</tt> : takes a single argument and returns :
<ul>
<li>the unchanged argument if it is recognized by Brython (if it has an attribute <tt>__class__</tt>)
<li>an instance of DOMObject (or DOMEvent) if the argument is a DOM object (or an event)
<li>else, an instance of JSObject wrapping the argument
</ul>
<li><tt>$MakeArgs</tt> called at the beginning of the execution of each function, and which signature consists of at least one argument. It builds a namespace based on the passed arguments, calling $JS2py on each of them
<li><tt>$list_comp</tt> is called for each list comprehension
<li><tt>$raise</tt> is called to raise exceptions
<li><tt>$test_expr</tt> and <tt>$test_item</tt> are used in the evaluation of <code>and</code> or <code>or</code> combined conditions
</ul>
<li>functions defined in <tt>py_import.js</tt> to manage imports
</ul>

<p>If there is a runtime error, a trace is printed in the browser console very closely modeled after one that would be generated by Python 

</ol>
</body>
</html>
